package com.scwatch.core.html;

import com.scwatch.common.web.PathResolver;
import com.scwatch.core.constant.Constants;
import com.scwatch.core.domain.*;
import com.scwatch.core.repository.InfoDao;
import com.scwatch.core.repository.NodeDao;
import com.scwatch.core.service.*;
import freemarker.template.Configuration;
import freemarker.template.TemplateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import java.io.IOException;
import java.util.*;

import static com.scwatch.core.domain.Node.*;

/**
 * HtmlServiceImpl
 * 
 * @author gjl
 * 
 */
@Service
@Transactional
public class HtmlServiceImpl implements HtmlService {
	private static final Logger logger = LoggerFactory
			.getLogger(HtmlServiceImpl.class);

	public void makeInfo(Integer infoId) {
		Info info = infoQuery.get(infoId);
		makeInfo(info);
	}

	public void makeInfo(Info info) {
		if (info == null) {
			return;
		}
//		FileHandler fileHandler = info.getSite().getHtmlPublishPoint()
//				.getFileHandler(pathResolver);
		try {
		    Map<String,Object> dataMap=new HashMap<>();

            List<Integer>  newInfo = infoDao.getHourNewInfo();
            if(newInfo!=null && newInfo.size()>0){
               dataMap.put("newInfo",infoQuery.get(newInfo.get(0)));
            }

            List<LiveBroadcastRoom> roomList=null;
            if(info!=null && info.getRefLive()!=null &&info.getRefLive().getId()!=null){
                roomList=roomService.getRoomListByParam(info.getRefLive().getId());
            }
            dataMap.put("roomList",roomList);
			PInfo.makeHtml(info, getConfig(), pathResolver, taskService, null,dataMap);
		} catch (Exception e) {
			logger.error(null, e);
		}
	}

	public void deleteInfo(Info info) {
		if (info == null) {
			return;
		}

//		FileHandler fileHandler = info.getSite().getHtmlPublishPoint()
//				.getFileHandler(pathResolver);
		try {
			PInfo.deleteHtml(info, pathResolver);
		} catch (Exception e) {
			logger.error(null, e);
		}
	}

	public void makeNode(Integer nodeId) {
		Node node = nodeQuery.get(nodeId);
		makeNode(node,null);
	}

	public void makeNode(Node node,String queryDate) {
		if (node == null) {
			return;
		}
		//卫视、节目回看栏目 添加相应生成数据
        Map<String,Object> dataMap=new HashMap<>();
        List<Programback> programbacks=null;
        if(node.getNodeModel()!=null && node.getNodeModel().getFlag()!=null){
            // 1.回看 数据
            if(Constants.MODEL_TV_of_yesterday.equals(node.getNodeModel().getFlag())
                    || Constants.MODEL_FLAG_SCTV.equals(node.getNodeModel().getFlag()) ){
                PageRequest pageable=new PageRequest(0,30000,new Sort(Sort.Direction.ASC,"id","time"));
                Map<String,String[]> paramMap=new HashMap<String,String[]>();
                paramMap.put("CONTAIN_name",new String[]{""});
                paramMap.put("EQ_site.id",new  String[]{String.valueOf(node.getSite().getId())});
                //节目频道
                Page<Programback> pagedList1 = programBackService.findAll(paramMap, pageable);
                programbacks=pagedList1.getContent();
                if(programbacks!=null && programbacks.size()>0){
                    for(Programback proBack:programbacks){
                        if(proBack!=null && proBack.getProgramDatecheacks()!=null && proBack.getProgramDatecheacks().size()>0){
                            int num=0;
                            for(ProgramDatecheack proDate:proBack.getProgramDatecheacks()){
                                if(num>=7){
                                    break;
                                }
                                Integer dateId=proDate.getId();
                                paramMap=new HashMap<String,String[]>();
                                paramMap.put("EQ_programDatecheack.id",new String[]{dateId.toString()});
                                pageable=new PageRequest(0,30000,new Sort(Sort.Direction.ASC,"time"));
                                Page<ProgramBackcode> pagedList2 = programBackCodeService.findAll(paramMap, pageable);
                                proDate.setProgramBackcodes(pagedList2.getContent());
                                num++;
                            }
                        }

                    }
                }
                dataMap.put("programbacks",programbacks);
                //2.卫视 电视直播节目单
                if(Constants.MODEL_FLAG_SCTV.equals(node.getNodeModel().getFlag())){
                    paramMap=new HashMap<String,String[]>();
                    paramMap.put("CONTAIN_name",new String[]{""});
                    paramMap.put("EQ_site.id",new  String[]{String.valueOf(node.getSite().getId())});
                    pageable=new PageRequest(0,30000);
                    Page<Sinatv> pagedList = sinatvService.findAll(paramMap, pageable);
                    dataMap.put("sinatvList",pagedList.getContent());
                }

            }
            //高层
            if(Constants.MODEL_FLAG_GC.equals(node.getNodeModel().getFlag())){
                Map<String,String[]> paramMap=new HashMap<String,String[]>();
                Pageable pageable=new PageRequest(0,30000,new Sort(Sort.Direction.DESC,"publishDate"));
                Pageable pageable3=new PageRequest(0,3,new Sort(Sort.Direction.DESC,"publishDate"));
                Pageable userPage=new PageRequest(0,30000,new Sort(Sort.Direction.DESC,"priority","id"));
                Page<GaoCeng> pagedList = gcService.findAll(paramMap, userPage);
                String userNewsFileName="/sctv/gaoceng/gaoceng_info_";
                for(GaoCeng gaoCeng : pagedList){
                    List<Special> specials = specialService.findBySpecialId(gaoCeng.getSpecial().getId());
                    Integer specialId[] = new Integer[specials.size()];
                    int i=0;
                    for(Special special : specials){
                        specialId[i] = special.getId();
                        ++i;
                    }
                    Page<Info> infoList =  infoQuery.findPage(null,null, null,
                            specialId, null,null , null,null, null,
                            null, null, null, null,null,
                            null, null, null, null,null,
                            null, null, null, new String[]{"A"},null, null,
                            null, null, null, null, null, null, pageable3,null,null,null,null);
                    gaoCeng.setNewsList(infoList.getContent());
                    Page<Info> userNewsList = infoQuery.findPage(null,null, null,
                            specialId, null,null , null,null, null,
                            null, null, null, null,null,
                            null, null, null, null,null,
                            null, null, null, new String[]{"A"},null, null,
                            null, null, null, null, null, null, pageable,null,null,null,null);
                    gaoCeng.setPageNewsList(userNewsList);
                    gaoCeng.setMoreNewsUrl(userNewsFileName+gaoCeng.getId()+".json");
                }

                dataMap.put("userList",pagedList.getContent());
            }
            //3时讯、24小时要闻
            if(Constants.MODEL_FLAG_CURRENTNEWS.equals(node.getNodeModel().getFlag())
                    || Constants.MODEL_FLAG_24HOURSNEWS.equals(node.getNodeModel().getFlag())){
                List<String> infoDates=infoQuery.getInfoDatesByParam(node.getId(),node.getSite().getId());
                List<String> isStick=infoQuery.getStickInfoDatesByParam(node.getId(),node.getSite().getId());
                dataMap.put("infoDates",infoDates);
                dataMap.put("queryDate",queryDate);
                dataMap.put("isStick",isStick);
            }
        }
		int method = node.getStaticMethodOrDef();
		// 触发生成只生成列表页第一页。
		int max = 1;
		if (STATIC_INFO_NODE_PARENT_LIST == method) {
			max = Integer.MAX_VALUE;
		}
//		FileHandler fileHandler;
		if (STATIC_INFO_NODE_PARENT == method
				|| STATIC_INFO_NODE_PARENT_LIST == method) {
			while (node != null) {
//				fileHandler = node.getSite().getHtmlPublishPoint()
//						.getFileHandler(pathResolver);
				try {
					PNode.makeHtml(node, max, getConfig(), pathResolver,
							taskService, null,dataMap);
				} catch (Exception e) {
					logger.error(null, e);
				}
				node = node.getParent();
			}
		} else if (STATIC_INFO_NODE == method) {
//			fileHandler = node.getSite().getHtmlPublishPoint()
//					.getFileHandler(pathResolver);
			try {

				PNode.makeHtml(node, max, getConfig(), pathResolver,
						taskService, null,dataMap);
			} catch (Exception e) {
				logger.error(null, e);
			}
		} else {
			// do nothing
		}
	}

	public void makeHome(Integer siteId) throws IOException, TemplateException {
		Node node = nodeQuery.findRoot(siteId);
		if (node != null) {
//			FileHandler fileHandler = node.getSite().getHtmlPublishPoint()
//					.getFileHandler(pathResolver);
			PNode.makeHtml(node, 1, getConfig(), pathResolver, taskService, null,null);
		}
	}

	public Integer makeInfo(Integer siteId, Integer nodeId,
			boolean includeChildren, Integer taskId, boolean forUpdate,
			Integer lastId, int maxResult) throws IOException,
			TemplateException {
		String treeNumber = null;
		if (includeChildren && nodeId != null) {
			Node node = nodeQuery.get(nodeId);
			treeNumber = node.getTreeNumber();
		}
		List<Info> list = infoDao.findForHtml(siteId, nodeId, treeNumber,
				forUpdate, lastId, maxResult);
//		FileHandler fileHandler;
		Iterator<Info> it = list.iterator();
		Info info;
		while (it.hasNext() && taskService.isRunning(taskId)) {
			info = it.next();
			lastId = info.getId();
//			fileHandler = info.getSite().getHtmlPublishPoint()
//					.getFileHandler(pathResolver);
            Map<String,Object> dataMap=new HashMap<>();
            List<LiveBroadcastRoom> roomList=null;
            if(info!=null && info.getRefLive()!=null &&info.getRefLive().getId()!=null){
                roomList=roomService.getRoomListByParam(info.getRefLive().getId());
            }
            dataMap.put("roomList",roomList);
			PInfo.makeHtml(info, getConfig(), pathResolver, taskService, taskId,dataMap);
		}
		if (list.size() < maxResult) {
			lastId = null;
		}
		return lastId;
	}

    @Override
    public Info generationInfo(Integer infoId,boolean toDelete) {
        Info info=infoQuery.get(infoId);
        Set<Info> beans = new HashSet<Info>();
        beans.add(info);
        Set<Info> infos = new HashSet<Info>();
        Set<Node> nodes = new HashSet<Node>();
        Node node;
        for (Info bean : beans) {
            node = bean.getNode();
            node.updateHtmlStatus();
            nodes.add(node);

            bean.updateHtmlStatus();
            if (bean.getNode().getStaticMethodOrDef() != Node.STATIC_MANUAL) {
                infos.add(bean);
            }
            Integer id = bean.getId();
            Info next = infoQuery.findNext(id, false);
            Info prev = infoQuery.findPrev(id, false);
            if (next != null) {
                next.updateHtmlStatus();
                if (next.getNode().getStaticMethodOrDef() != Node.STATIC_MANUAL) {
                    infos.add(next);
                }
            }
            if (prev != null) {
                prev.updateHtmlStatus();
                if (prev.getNode().getStaticMethodOrDef() != Node.STATIC_MANUAL) {
                    infos.add(prev);
                }
            }
        }
        for (Info i : infos) {
            if (toDelete) {
                deleteInfo(i);
            } else {
                makeInfo(i);
            }
        }
        for (Node n : nodes) {
            makeNode(n,null);
        }
        return info;
    }

    @Override
    public List<Info> generationInfo(List<Integer> infoIds,boolean toDelete) {
        List<Info> beans=infoDao.findAll(infoIds);
        Set<Info> infos = new HashSet<Info>();
        Set<Node> nodes = new HashSet<Node>();
        Node node;
        for (Info bean : beans) {
            node = bean.getNode();
            node.updateHtmlStatus();
            nodes.add(node);

            bean.updateHtmlStatus();
            if (bean.getNode().getStaticMethodOrDef() != Node.STATIC_MANUAL) {
                infos.add(bean);
            }
            Integer id = bean.getId();
            Info next = infoQuery.findNext(id, false);
            Info prev = infoQuery.findPrev(id, false);
            if (next != null) {
                next.updateHtmlStatus();
                if (next.getNode().getStaticMethodOrDef() != Node.STATIC_MANUAL) {
                    infos.add(next);
                }
            }
            if (prev != null) {
                prev.updateHtmlStatus();
                if (prev.getNode().getStaticMethodOrDef() != Node.STATIC_MANUAL) {
                    infos.add(prev);
                }
            }
        }
        for (Info i : infos) {
            if (toDelete) {
                deleteInfo(i);
            } else {
                makeInfo(i);
            }
        }
        for (Node n : nodes) {
            makeNode(n,null);
        }
        return beans;
    }

    public Integer makeNode(Integer siteId, Integer nodeId,
			boolean includeChildren, Integer taskId, boolean forUpdate,
			Integer lastId, int maxResult,String queryDate) throws IOException,
			TemplateException {
		String treeNumber = null;
		if (includeChildren && nodeId != null) {
			Node node = nodeQuery.get(nodeId);
			treeNumber = node.getTreeNumber();
		}
		List<Node> list = nodeDao.findForHtml(siteId, nodeId, treeNumber,
				forUpdate, lastId, maxResult);
//		FileHandler fileHandler;
		Iterator<Node> it = list.iterator();
		Node node;
		while (it.hasNext() && taskService.isRunning(taskId)) {
			node = it.next();
            //卫视、节目回看栏目 添加相应生成数据
            Map<String,Object> dataMap=new HashMap<>();
            List<Programback> programbacks=null;
            if(node.getNodeModel()!=null && node.getNodeModel().getFlag()!=null){
                // 1.回看 数据
                if(Constants.MODEL_TV_of_yesterday.equals(node.getNodeModel().getFlag())
                        || Constants.MODEL_FLAG_SCTV.equals(node.getNodeModel().getFlag()) ){
                    PageRequest pageable=new PageRequest(0,30000,new Sort(Sort.Direction.ASC,"id","time"));
                    Map<String,String[]> paramMap=new HashMap<String,String[]>();
                    paramMap.put("CONTAIN_name",new String[]{""});
                    paramMap.put("EQ_site.id",new  String[]{String.valueOf(node.getSite().getId())});
                    //节目频道
                    Page<Programback> pagedList1 = programBackService.findAll(paramMap, pageable);
                    programbacks=pagedList1.getContent();
                    if(programbacks!=null && programbacks.size()>0){
                        for(Programback proBack:programbacks){
                            if(proBack!=null && proBack.getProgramDatecheacks()!=null && proBack.getProgramDatecheacks().size()>0){
                                int num=0;
                                for(ProgramDatecheack proDate:proBack.getProgramDatecheacks()){
                                    if(num>=7){
                                        break;
                                    }
                                    Integer dateId=proDate.getId();
                                    paramMap=new HashMap<String,String[]>();
                                    paramMap.put("EQ_programDatecheack.id",new String[]{dateId.toString()});
                                    pageable=new PageRequest(0,30000,new Sort(Sort.Direction.ASC,"time"));
                                    Page<ProgramBackcode> pagedList2 = programBackCodeService.findAll(paramMap, pageable);
                                    proDate.setProgramBackcodes(pagedList2.getContent());
                                    num++;
                                }
                            }

                        }
                    }
                    dataMap.put("programbacks",programbacks);
                    //2.卫视 电视直播节目单
                    if(Constants.MODEL_FLAG_SCTV.equals(node.getNodeModel().getFlag())){
                        paramMap=new HashMap<String,String[]>();
                        paramMap.put("CONTAIN_name",new String[]{""});
                        paramMap.put("EQ_site.id",new  String[]{String.valueOf(node.getSite().getId())});
                        pageable=new PageRequest(0,30000);
                        Page<Sinatv> pagedList = sinatvService.findAll(paramMap, pageable);
                        dataMap.put("sinatvList",pagedList.getContent());
                    }
                }

                //3时讯、24小时要闻
                if(Constants.MODEL_FLAG_CURRENTNEWS.equals(node.getNodeModel().getFlag())
                        || Constants.MODEL_FLAG_24HOURSNEWS.equals(node.getNodeModel().getFlag())){
                    List<String> infoDates=infoQuery.getInfoDatesByParam(node.getId(),node.getSite().getId());
                    List<String> isStick=infoQuery.getStickInfoDatesByParam(node.getId(),node.getSite().getId());
                    dataMap.put("infoDates",infoDates);
                    dataMap.put("queryDate",queryDate);
                    dataMap.put("isStick",isStick);
                }
            }
			lastId = node.getId();
//			fileHandler = node.getSite().getHtmlPublishPoint()
//					.getFileHandler(pathResolver);
			PNode.makeHtml(node, Integer.MAX_VALUE, getConfig(), pathResolver,
					taskService, taskId,dataMap);
		}
		if (list.size() < maxResult) {
			lastId = null;
		}
		return lastId;
	}

	private Configuration getConfig() {
		return freeMarkerConfigurer.getConfiguration();
	}

	private PathResolver pathResolver;
	private FreeMarkerConfigurer freeMarkerConfigurer;
	private TaskService taskService;
	private InfoQueryService infoQuery;
	private NodeQueryService nodeQuery;
    @Autowired
    private ProgramBackCodeService programBackCodeService;
    @Autowired
    private ProgramBackService programBackService;
    @Autowired
    private ProgramDatecheckService programService;
    @Autowired
    private SinatvService sinatvService;
    @Autowired
    private GcService gcService;
    @Autowired
    private LiveBroadcastRoomService roomService;

    @Autowired
    private SpecialService specialService;

	@Autowired
	public void setPathResolver(PathResolver pathResolver) {
		this.pathResolver = pathResolver;
	}

	@Autowired
	public void setFreeMarkerConfigurer(
			FreeMarkerConfigurer freeMarkerConfigurer) {
		this.freeMarkerConfigurer = freeMarkerConfigurer;
	}

	@Autowired
	public void setTaskService(TaskService taskService) {
		this.taskService = taskService;
	}

	@Autowired
	public void setInfoQuery(InfoQueryService infoQuery) {
		this.infoQuery = infoQuery;
	}

	@Autowired
	public void setNodeQuery(NodeQueryService nodeQuery) {
		this.nodeQuery = nodeQuery;
	}

	private InfoDao infoDao;
	private NodeDao nodeDao;

	@Autowired
	public void setInfoDao(InfoDao infoDao) {
		this.infoDao = infoDao;
	}

	@Autowired
	public void setNodeDao(NodeDao nodeDao) {
		this.nodeDao = nodeDao;
	}

}
